package com.winter.payService;


import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeAppPayModel;
import com.alipay.api.request.AlipayTradeAppPayRequest;
import com.alipay.api.response.AlipayTradeAppPayResponse;
import com.winter.mapper.DatumDownloadMapper;
import com.winter.mapper.NewDatumOrderMapper;
import com.winter.model.NewDatumOrder;
import com.winter.model.vo.HandleOrderVo;
import com.winter.util.Constants;
import com.winter.util.Result;
import com.winter.util.ResultCode;
import com.winter.util.UUIDUitls;
import com.winter.util.json.JsonUtils;
import com.winter.util.payConfig.AliPayConfig;
import com.winter.util.payConfig.AliPayUtil;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.net.URLDecoder;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Service
public class AliPayService {

    protected Logger logger = LoggerFactory.getLogger(AliPayService.class);

    @Autowired
    private NewDatumOrderMapper newDatumOrderMapper;

    @Autowired
    private DatumDownloadMapper datumDownloadMapper;

    /**
     * 支付宝支付调用需要参数
     *
     * @param body               订单描述（自定义）
     * @param subject            订单标题（自定义）
     * @param out_trade_no（订单id） 商户订单号 orderSn
     * @param total_amount       订单总金额，单位为元，精确到小数点后
     */
    public Result returnAlipayPayParam(String body, String subject, String out_trade_no, String total_amount, String param) throws Exception {
        Result result = new Result();
        //实例化客户端
        AlipayClient alipayClient = new DefaultAlipayClient(AliPayConfig.GATE,
                AliPayConfig.ALIPAY_APP_ID,
                AliPayConfig.ALIPAY_PRIVATE_KEY,
                "json", AliPayConfig.ALIPAY_CHARSET,
                AliPayConfig.ALIPAY_PUBLIC_KEY,
                "RSA2");
        if (Double.valueOf(total_amount) <= 0) { // 一些必要的验证，防止抓包恶意修改支付金额
            return null;
        }

        //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称：alipay.trade.app.pay
        AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
        //SDK已经封装掉了公共参数，这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。
        AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
        model.setBody(body);
        model.setSubject(subject);
        model.setSellerId(AliPayConfig.ALIPAY_PARTNER);
        model.setOutTradeNo(System.currentTimeMillis() + "");  //订单号
        model.setTimeoutExpress("30m");  // 该参数数值不接受小数点， 如 1.5h，可转换为 90m。
        model.setTotalAmount(total_amount); // 订单总金额，单位为元，精确到小数点后两位，取值范围[0.01,100000000]这里调试每次支付1分钱，在项目上线前应将此处改为订单的总金额
        model.setProductCode("QUICK_MSECURITY_PAY");// 销售产品码，商家和支付宝签约的产品码，为固定值QUICK_MSECURITY_PAY
        model.setPassbackParams(param);
        request.setBizModel(model);
        // 设置后台异步通知的地址，在手机端支付成功后支付宝会通知后台，手机端的真实支付结果依赖于此地址
        request.setNotifyUrl(AliPayConfig.PAY_NOTIFY_URL);
        try {
            //这里和普通的接口调用不同，使用的是sdkExecute
            AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
            System.out.println(response.getBody());//就是orderString 可以直接给客户端请求，无需再做处理。
            if (response.isSuccess()) {
                return Result.success(response.getBody());
            } else {
                return Result.failure(ResultCode.PARAM_IS_BLANK, "支付失败");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return Result.success();

    }


    /**
     * 支付宝回调
     */
    public String aliNotify(HttpServletRequest request, HttpServletResponse response) throws Exception {
        String returnStr = "";
        try {
            Map<String, String> params = new HashMap<String, String>();
            Map requestParams = request.getParameterMap();
            for (Iterator iter = requestParams.keySet()
                                              .iterator(); iter.hasNext(); ) {
                String name = (String) iter.next();
                String[] values = (String[]) requestParams.get(name);
                String valueStr = "";
                for (int i = 0; i < values.length; i++) {
                    valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
                }
                params.put(name, valueStr);
            }
            logger.info("====================================================param params:" + params);
            String trade_status = params.get("trade_status");
            logger.info("支付的状态：" + trade_status);
            if (trade_status != null && trade_status.equals("TRADE_SUCCESS")) {
                /**
                 *支付成功之后的业务处理
                 */
                // 获取用户userNo
                String back_param = params.get("passback_params");
                String param = URLDecoder.decode(back_param, "utf-8");
                String total_amount = params.get("total_amount");
                String totalAmount = URLDecoder.decode(total_amount, "utf-8");
                HandleOrderVo handleOrderVo = JSONObject.parseObject(param, HandleOrderVo.class);
                if (handleOrderVo != null) {
                    // 新增订单
                    handleOrder(handleOrderVo.getUserNo(), handleOrderVo.getDatumId(), totalAmount, Constants.ALI);
                }
                returnStr = "success";
            } else {
                /**
                 *支付失败后的业务处理
                 */
                returnStr = "failure";
            }
        } catch (Exception e) {
            e.printStackTrace();
            returnStr = "failure";
        }
        return returnStr;
    }

    /**
     * 新增订单
     */
    public void handleOrder(String userNo, String outTradeNo, String totalAmount, String type) {
        NewDatumOrder newDatumOrder1 = newDatumOrderMapper.queryUserNoAndDatumId(userNo, outTradeNo);
        if (newDatumOrder1 == null) {
            NewDatumOrder newDatumOrder = new NewDatumOrder();
            newDatumOrder.setCreatedAt(new Date());
            newDatumOrder.setDatumId(new BigDecimal(outTradeNo));
            newDatumOrder.setId(UUIDUitls.uuid());
            newDatumOrder.setPayType(type);
            newDatumOrder.setUserNo(userNo);
            newDatumOrder.setPrice(Double.valueOf(totalAmount));
            newDatumOrderMapper.insertSelective(newDatumOrder);
            // 更新下载量
            datumDownloadMapper.updateNum(outTradeNo);
        }
    }
}
